package eclant.ant.types;

import java.io.File;

import org.apache.tools.ant.types.selectors.SelectorUtils;
import org.eclipse.core.resources.IResource;
import org.eclipse.jdt.core.IClasspathContainer;

import eclant.ant.types.FileSetClasspathVisitor.EntryKind;
import eclant.ant.types.FileSetClasspathVisitor.EntrySelector;

final class ClasspathEntrySelector implements EntrySelector
{
	public static enum FileType
	{
		file(IResource.FILE), dir(IResource.FOLDER), folder(IResource.FOLDER);

		private final int type;

		FileType(int type)
		{
			this.type = type;
		}

		public boolean isSelected(IResource resource)
		{
			return resource.getType() == this.type;
		}

		public boolean isSelected(File file)
		{
			return (this.type == IResource.FILE && file.isFile())
					|| (this.type == IResource.FOLDER && file.isDirectory());
		}
	}

	private final EntryKind matchKind;
	private final EntryKind matchSrcKind;
	private final FileType type;
	private final String conName;
	private final ResourceSelector select;
	private final int[] conKinds;

	ClasspathEntrySelector(EntryKind kind, EntryKind srcKind, FileType type, String container,
			int[] conKinds, ResourceSelector rs)
	{
		this.matchKind = kind;
		this.matchSrcKind = srcKind;
		this.type = type;
		this.conName = container;
		this.conKinds = conKinds;
		this.select = rs;
	}

	@Override
	public boolean isSelected(EntryKind kind, File library, EntryKind srcKind,
			IClasspathContainer container)
	{
		if (!isSelected(kind, srcKind, container))
			return false;
		else if (type != null && !type.isSelected(library))
			return false;
		else if (select == null)
			return true;
		else
		{
			// String name = library.getName();
			String name = library.getPath();
			return select.isIncluded(name) && !select.isExcluded(name)
					&& select.isSelected(library.getParentFile(), library.getName(), library);
		}
	}

	@Override
	public boolean isSelected(EntryKind kind, IResource resource, EntryKind srcKind,
			IClasspathContainer container)
	{
		if (!isSelected(kind, srcKind, container))
			return false;
		else if (type != null && !type.isSelected(resource))
			return false;
		else if (select == null)
			return true;
		else
		{
			// String name = resource.getName();
			String name = resource.getFullPath().toPortableString();
			File file = resource.getFullPath().toFile();
			return select.isIncluded(name) && !select.isExcluded(name)
					&& select.isSelected(file.getParentFile(), resource.getName(), file);
		}
	}

	private boolean isSelected(EntryKind kind, EntryKind srcKind, IClasspathContainer container)
	{
		if (matchKind != null && !matchKind.equals(kind))
			return false;
		else if (matchSrcKind != null && !matchSrcKind.equals(srcKind))
			return false;

		// match container
		else if (conName != null)
			return container != null
					&& SelectorUtils.match(conName, container.getPath().toPortableString())
					&& (conKinds == null || includeContainerKind(container.getKind()));
		else if (conKinds != null)
			return container != null && includeContainerKind(container.getKind());
		else
			return container == null || container.getKind() == IClasspathContainer.K_APPLICATION;
	}

	private boolean includeContainerKind(int kind)
	{
		for (int i : conKinds)
		{
			if (kind == i)
				return true;
		}

		return false;
	}
}
